<template>
  <view class="lSwipeAction">
    <view class="swipe-item" :class="[isShowBtn ? 'swipe-action-show' : '']"
      :style="{ transform: 'translate(' + position.pageX + 'px,0)' }">
      <view class="swipe-content" @touchstart="onTouchstart" @touchmove="onTouchmove" @touchend="onTouchend"
        @mousedown="onTouchstart" @mousemove="onTouchmove" @mouseup="onTouchend">
        <slot></slot>
      </view>
      <view class="swipe-button-right-group" v-if="options.length > 0" @touchend.stop="loop">
        <view class="swipe-button-right-item" v-for="(item, index) in options" :key="index"
          :style="{ backgroundColor: item.background || '#f7f7f7', color: item.color, width: item.width + 'rpx' }"
          :data-index="index" @tap="handlerButton(data, index)">
          <text>{{ item.name }}</text>
        </view>
      </view>
    </view>
    <view v-if="isShowBtn && showMask" class="swipe-action-mask" @tap.stop="closeSwipe"
      @touchstart.stop.prevent="closeSwipe"></view>
  </view>
</template>

<script>
  export default {
    name: 'lSwipeAction',
    props: {
      data: {
        type: Object,
      },
      options: {
        type: Array,
        default () {
          return [];
        }
      },
      //点击按钮时是否自动关闭
      isClickClose: {
        type: Boolean,
        default: false
      },
      //设为false，点其他地方不关闭菜单可以用来滑动多行
      showMask: {
        type: Boolean,
        default: true
      },
    },
    watch: {
      options(newValue, oldValue) {
        this.updateMovesize();
      },
    },
    data() {
      return {
        startPos: {
          pageX: 0,
          pageY: 0
        },
        //限制滑动距离
        moveSize: 0,
        position: {
          pageX: 0,
          pageY: 0
        },
        isShowBtn: false,
        move: false
      };
    },
    mounted() {
      this.updateMovesize();
    },
    methods: {
      swipeDirection(x1, x2, y1, y2) {
        return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : y1 - y2 > 0 ? 'Up' :
          'Down';
      },
      //阻止事件冒泡
      loop() {},
      updateMovesize() {
        let win = uni.getSystemInfoSync().windowWidth / 750
        if (this.options.length > 0) {
          this.moveSize = 0;
          this.options.forEach(item => {
            this.moveSize += Math.floor(item.width * win);
          });
        }
      },
      onTouchstart(event) {
        if (this.options.length == 0) return;
        let touches = event.touches
        if (touches && touches.length > 1) return;
        this.move = true;
        touches = touches ? event.touches[0] : {};
        if (!touches || (touches.pageX === undefined && touches.pageY === undefined)) {
          touches = {
            pageX: event.pageX,
            pageY: event.pageY
          };
        }
        const startPos = this.startPos;
        if (touches) {
          for (let i in startPos) {
            if (touches[i]) {
              startPos[i] = touches[i];
            }
          }
        }
      },
      swipper(touches) {
        const start = this.startPos;
        const spacing = {
          pageX: touches.pageX - start.pageX,
          pageY: touches.pageY - start.pageY
        };
        if (this.moveSize < Math.abs(spacing.pageX)) {
          spacing.pageX = -this.moveSize;
        }
        this.position = spacing;
      },
      onTouchmove(event) {
        if (this.options.length == 0 || !this.move) return;
        const start = this.startPos;
        let touches = event.touches ? event.touches[0] : {};
        if (!touches || (touches.pageX === undefined && touches.pageY === undefined)) {
          touches = {
            pageX: event.pageX,
            pageY: event.pageY
          };
        }
        if (touches) {
          const direction = this.swipeDirection(start.pageX, touches.pageX, start.pageY, touches.pageY);
          if (direction === 'Left' && Math.abs(this.position.pageX) !== this.moveSize) {
            this.swipper(touches);
          }
        }
      },
      onTouchend(event) {
        if (this.options.length == 0 || !this.move) return;
        this.move = false;
        const start = this.startPos;
        let touches = event.changedTouches ? event.changedTouches[0] : {};
        if (!touches || (touches.pageX === undefined && touches.pageY === undefined)) {
          touches = {
            pageX: event.pageX,
            pageY: event.pageY
          };
        }
        if (touches) {
          const direction = this.swipeDirection(start.pageX, touches.pageX, start.pageY, touches.pageY);
          const spacing = {
            pageX: touches.pageX - start.pageX,
            pageY: touches.pageY - start.pageY
          };
          if (Math.abs(spacing.pageX) >= 40 && direction === 'Left') {
            spacing.pageX = spacing.pageX < 0 ? -this.moveSize : this.moveSize;
            this.isShowBtn = true;
          } else {
            spacing.pageX = 0;
          }
          if (spacing.pageX == 0) {
            this.isShowBtn = false;
          }
          this.position = spacing;

        }
      },
      handlerButton(data, index) {
        if (this.isClickClose) {
          this.closeSwipe();
        }
        this.$emit('clickItem', {
          data,
          index
        });
      },
      closeSwipe() {
        this.position = {
          pageX: 0,
          pageY: 0
        };
        this.isShowBtn = false;
      },
    }
  };
</script>

<style lang="scss" scoped>
  .lSwipeAction {
    position: relative;
    overflow: hidden;

    .swipe-action-show {
      position: relative;
      z-index: 998;
    }

    .swipe-item {
      width: 100%;
      box-sizing: border-box;
      transition: transform 0.2s ease;
      font-size: 14px;
      cursor: pointer;

      .swipe-content {
        white-space: nowrap;
        overflow: hidden;
      }

      .swipe-button-right-group {
        position: absolute;
        right: -100%;
        top: 0;
        height: 100%;
        z-index: 1;
        width: 100%;

        .swipe-button-right-item {
          height: 100%;
          float: left;
          white-space: nowrap;
          box-sizing: border-box;
          display: flex;
          align-items: center;
          justify-content: center;
          text-align: center;
        }
      }
    }

    .swipe-action-mask {
      display: block;
      opacity: 0;
      position: fixed;
      z-index: 997;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
  }
</style>
